package com.example.service.impl;

import com.example.entity.JobEntity;
import com.example.repository.JobRepository;
import com.example.service.JobService;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class JobServiceImpl implements JobService {

    @Autowired
    private Scheduler scheduler;

    @Autowired
    private JobRepository jobRepository;

    @Override
    public JobEntity addJob(JobEntity jobEntity) throws Exception {
        if (jobRepository.existsByJobNameAndJobGroup(jobEntity.getJobName(), jobEntity.getJobGroup())) {
            throw new Exception("Job already exists");
        }

        // 先保存任务实体
        jobEntity.setStatus("NORMAL");
        jobEntity.setUpdateTime(System.currentTimeMillis());
        jobEntity = jobRepository.save(jobEntity);

        // 创建JobDetail和Trigger
        Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(jobEntity.getJobClass());
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(jobEntity.getJobName(), jobEntity.getJobGroup())
                .withDescription(jobEntity.getDescription())
                .usingJobData("jobData", jobEntity.getJobData())
                .build();

        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(jobEntity.getJobName(), jobEntity.getJobGroup())
                .withSchedule(CronScheduleBuilder.cronSchedule(jobEntity.getCronExpression()))
                .build();

        // 调度任务
        scheduler.scheduleJob(jobDetail, trigger);
        
        return jobEntity;
    }

    @Override
    public void updateJob(JobEntity jobEntity) throws Exception {
        JobEntity existingJob = jobRepository.findByJobNameAndJobGroup(jobEntity.getJobName(), jobEntity.getJobGroup());
        if (existingJob == null) {
            throw new Exception("Job not found");
        }

        TriggerKey triggerKey = TriggerKey.triggerKey(jobEntity.getJobName(), jobEntity.getJobGroup());
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerKey)
                .withSchedule(CronScheduleBuilder.cronSchedule(jobEntity.getCronExpression()))
                .build();

        scheduler.rescheduleJob(triggerKey, trigger);

        existingJob.setCronExpression(jobEntity.getCronExpression());
        existingJob.setDescription(jobEntity.getDescription());
        existingJob.setStatus("NORMAL");
        existingJob.setUpdateTime(System.currentTimeMillis());
        jobRepository.save(existingJob);
    }

    @Override
    public void deleteJob(String jobName, String jobGroup) throws Exception {
        JobEntity jobEntity = jobRepository.findByJobNameAndJobGroup(jobName, jobGroup);
        if (jobEntity == null) {
            throw new Exception("Job not found");
        }

        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.deleteJob(jobKey);
        jobRepository.delete(jobEntity);
    }

    @Override
    public void pauseJob(String jobName, String jobGroup) throws Exception {
        JobEntity jobEntity = jobRepository.findByJobNameAndJobGroup(jobName, jobGroup);
        if (jobEntity == null) {
            throw new Exception("Job not found");
        }

        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.pauseJob(jobKey);

        jobEntity.setStatus("PAUSED");
        jobEntity.setUpdateTime(System.currentTimeMillis());
        jobRepository.save(jobEntity);
    }

    @Override
    public void resumeJob(String jobName, String jobGroup) throws Exception {
        JobEntity jobEntity = jobRepository.findByJobNameAndJobGroup(jobName, jobGroup);
        if (jobEntity == null) {
            throw new Exception("Job not found");
        }

        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.resumeJob(jobKey);

        jobEntity.setStatus("NORMAL");
        jobEntity.setUpdateTime(System.currentTimeMillis());
        jobRepository.save(jobEntity);
    }

    @Override
    public JobEntity getJob(String jobName, String jobGroup) {
        return jobRepository.findByJobNameAndJobGroup(jobName, jobGroup);
    }

    @Override
    public List<JobEntity> getAllJobs() {
        return jobRepository.findAll();
    }

    @Override
    public List<JobEntity> getJobsByGroup(String jobGroup) {
        return jobRepository.findByJobGroup(jobGroup);
    }
}